SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00017 HARDWARE DETECTION 1 05-28-9313:48ALL SWAG SUPPORT TEAM Write to TWO Monitors IMPORT 9 └╫å# {π> Hi I am looking For some help on use 2 monitors at the same time... 1π> is mono and the other is vga. I would like to just post a certainπ> screen on the mono and leave the vga like normal..ππVGA Text mode memory begins at $b800, VGA Graphics memory at $A000, andπMDA/Herc memory begins at $b000. If you plan on running Text and Text,πtry something like this:π}πTypeπ WhichMonitor = (MDA, VGA);ππProcedure ChangeCel (Row, Column, Foreground, Background, Character : Byte;π Which : WhichMonitor);πVarπ Point : Word;πbeginπ If Which = MDA thenπ Point := $b000π elseπ Point := $b800;π MemW[Point : (Row - 1) * 160 + Col * 2] :=π (Foreground + Background * 16) * 256 + Character;π end;π{πOf course, there are more optimized ways to do this, but this shouldπportray the basic concept. Herc Graphics and VGA Graphics would beπdone in much the same manner, but I don't have an Herc With my VGA toπcheck it.π} 2 05-28-9313:48ALL SWAG SUPPORT TEAM ALOCSIZE.PAS IMPORT 21 └╫┬y *--* 03-31-93 - 21:47:03 *--*π/. Date: 03-30-93 (23:45) Number: 24023 of 24035π To: PEDRO PACHECO Refer#: 23957πFrom: ERIC LU Read: NOπSubj: allocation Units Status: PUBLIC MESSAGEπConf: R-TP (552) Read Type: GENERAL (A) (+)ππPP>> Is there any way to find (in Pascal) what's de size of each allocation uniπPP>> in a Hard drive?ππPedro,π See if the following is what you wanted...ππ-------------------------------- Cut ----------------------------------ππProgram Int21_36;πUses Crt,Dos;πProcedure DiskfreeSpace( DriveCode: Byte);πVarπ Regs: Registers;π SectorsPerCluster,π AvailableClusters,π BytesPerSector,π ClustersPerDrive,π(63 min left), (H)elp, More? AllocationSize,π Capacity,π Free: LongInt;πbeginπ Regs.AH := $36;π Regs.DL := DriveCode;π MSDos(Regs);ππ {************* Obtaining Infos ******************}π SectorsPerCLuster:= Regs.AX;π AvailableClusters:= Regs.BX;π BytesPerSEctor := Regs.CX;π ClustersPerDrive := Regs.DX;ππ {************* Calculations ********************)π AllocationSize := BytesPerSector * SectorsPerCluster;π Capacity := SectorsPerCluster * BytesPerSector * ClustersPerDrive;π Free := SectorsPerCLuster * AvailableClusters * BytesPerSector;ππ {************* Display *************************}π Writeln(' Sectors Per Cluster = ',SectorsPerCluster:15,'');π Writeln(' Available Clusters = ',AvailableClusters:15,'');π Writeln(' Bytes Per Sector = ',BytesPerSector:15,'');π(63 min left), (H)elp, More? Writeln(' Clusters Per Drive = ',ClustersPerDrive:15,'');π Writeln(' Allocation Size = ',AllocationSize:15,' Bytes');π Writeln(' Drive Capacity = ',Capacity:15,' Bytes');π Writeln(' Free Space = ',Free:15,' Bytes');πend;ππbeginπ ClrScr;π DiskFreeSpace(0); {Get Current Drive Info}π readln;πend.πππ----------------------------- Cut ----------------------------------ππ The above should be ready to run as I have tested on my computer..π It's got more infos.. I was learning it as I was typing it in so Iπ made it more than what you need.π hope this is what you wanted to know...ππ Ericππ---π(63 min left), (H)elp, More? ■ OLX 2.1 TD ■ It's only a hobby ... only a hobby ... only aπ * Casino Bulletin Board * Hammonton/Atlantic City NJ U.S.A. 1-609-561-3377π * PostLink(tm) v1.05 CASINO (#18) : RelayNet(tm)ππ(63 min left), (H)elp, end of Message Command? 3 05-28-9313:48ALL SWAG SUPPORT TEAM Determine Cluster Size IMPORT 5 └╫8∩ {π> Is there any way to find the size of each allocation Unit in a Hard drive?π}ππUses Dos;ππFunction clustsize (drive : Byte) : Word;πVarπ regs : Registers;πbeginπ regs.cx := 0; {set For error-checking just to be sure}π regs.ax := $3600; {get free space}π regs.dx := drive; {0=current, 1=a:, 2=b:, etc.}π msDos (regs);π clustsize := regs.ax * regs.cx; {cluster size!}πend;ππbeginπ Writeln(ClustSize(0));πend. 4 05-28-9313:48ALL SWAG SUPPORT TEAM CPU-ID.PAS IMPORT 12 └╫m╔ {π> How do i get info about witch CPU it is in the current computer??π}ππ{$F+}ππConstπ CPU_Type : Array[1..4] of String[5] = ('8086', '80286', '80386', '80486');π Cpu8086 = 1;π Cpu80286 = 2;π Cpu80386 = 3;π Cpu80486 = 4;πVarπ Result : Byte;πππFunction GetCPU_Type: Byte; Assembler;ππAsmπ MOV DX,Cpu8086π PUSH SPπ POP AXπ CMP SP,AXπ JNE @OUTπ MOV DX, Cpu80286π PUSHFπ POP AXπ or AX,4000hπ PUSH AXπ POPFπ PUSHFπ POP AXπ TEST AX,4000hπ JE @OUTπ MOV DX, Cpu80386π {"DB 66h" indicates '386 extended instruction}π DB 66h; MOV BX, SP {MOV EBX, ESP}π DB 66h, 83h, 0E4h, 0FCh {AND ESP, FFFC}π DB 66h; PUSHF {PUSHFD}π DB 66h; POP AX {POP EAX}π DB 66h; MOV CX, AX {MOV ECX, EAX}π DB 66h, 35h, 00hπ DB 00h, 04h, 00 {XOR EAX, 00040000}π DB 66h; PUSH AX {PUSH EAX}π DB 66h; POPF {POPFD}π DB 66h; PUSHF {PUSHFD}π DB 66h; POP AX {POP EAX}π DB 66h, 25h, 00hπ DB 00h, 04h, 00h {AND EAX, 00040000}π DB 66h, 81h, 0E1h, 00hπ DB 00h, 04h, 00h {AND ECX, 00040000}π DB 66h; CMP AX, CX {CMP EAX, ECX}π JE @Not486π MOV DX, Cpu80486π@Not486:π DB 66h; PUSH CX {PUSH EXC}π DB 66h; POPF {POPFD}π DB 66h; MOV SP, BX {MOV ESP, EBX}π@Out:π MOV AX, DXπend;ππbeginπ Result := GetCPU_Type;π Writeln(Result);πend.π 5 05-28-9313:48ALL SWAG SUPPORT TEAM Determine CPU Speed IMPORT 13 └╫Z {π· Subject: How to determine mhz using TP6.0...ππIt seems to work pretty well, but on a 486/33DX it gave inacurate results...π}ππProgram CpuSpeed;πUsesπ Crt;πVarπ Speed, DelayCalibrate : Word;πConstπ Offset = 9; { For TP 4.0, it should be 16 }πππProcedure WaitForFloppy;πVarπ tickTil : LongInt;π TimerTicks : LongInt Absolute $40 : $6C;π motorStatus : Byte Absolute $40 : $3F;πbeginπ if MotorStatus and $F > 0 thenπ beginπ WriteLn('Loading...');π TickTil := TimerTicks + 91;π {There are $17FE80 ticks in a day}π if TickTil > $17FE80 thenπ Dec(TickTil, $17FE80);π Repeat Until (MotorStatus and $F = 0) or (TimerTicks >= TickTil);π end;πend;ππbeginπ WaitForFloppy;π DelayCalibrate := MemW[Seg(CheckSnow): Ofs(CheckSnow)+Offset];π WriteLn('Delay calibration value is ', DelayCalibrate);π Speed := ((LongInt(1000) * DelayCalibrate) + 110970) div 438;π Write('Calculated speed: ', Speed div 100,'.');π WriteLn((speed div 10) MOD 10, speed MOD 10);π Write('CPU speed is probably ');π Case Speed OFπ 0..499 : WriteLn('4.77MHz or below');π 500..699 : WriteLn('6MHz');π 700..899 : WriteLn('8MHz');π 900..1099 : WriteLn('10MHz');π 1100..1399 : WriteLn('12MHz');π 1400..1799 : WriteLn('16MHz');π 1800..2199 : WriteLn('20MHz');π 2200..2699 : WriteLn('25MHz');π 2700..3599 : WriteLn('30MHz');π ELSEπ WriteLn('30MHz or MORE!');π end;πend.π 6 05-28-9313:48ALL SWAG SUPPORT TEAM FLOPSIZE.PAS IMPORT 10 └╫1 {π>Does anybody know how to determine the size of a disk drive. I meanπ>whether it is a 360 K drive or 720 K, 1.4 M or 1.2 M drive. I'mπ>working on a Program which has the ability to Format diskettes andπ>I want it to be able to come up With the size of a disk drive as aπ>default. I have looked at the equipment flag in the BIOS and theπ>only thing I can get out of that is the Type of a disk drive not theπ>size.π}πFunction VarCMOS(i : Byte) : Byte ;πbeginπ port[$70]:=i;π VarCMOS:=port[$71]πend;ππVar b : Byte ;ππbeginπ b:=VarCMOS($10);π if b and $f0<>0 thenπ beginπ Write('Drive A: = ');π Case (b and $f0) shr 4 ofπ 1 : Write('5" 360 Ko');π 2 : Write('5" 1,2 Mo');π 3 : Write('3" 720 Ko');π 4 : Write('3" 1,44 Mo')π end;π end;π if b and $f<>0 thenπ beginπ Write(', B: = ');π Case b and $f ofπ 1 : Writeln('5" 360 Ko');π 2 : Writeln('5" 1,2 Mo');π 3 : Writeln('3" 720 Ko');π 4 : Writeln('3" 1,44 Mo')π end;π end else WriteLn ;πend.π 7 05-28-9313:48ALL SWAG SUPPORT TEAM LPT-ADDR.PAS IMPORT 5 └╫└' {πOr better yet, the BIOS stores the addresses of the parallel Interfacesπon the system at memory location $0040:$0008. There are four Wordsπhere, allowing up to 4 parallel devices.π-Brian Papeπ}πVarπ i : Byte;π par : Array[1..4] of Word;πbeginπ For i := 1 to 4 doπ beginπ par[i] := Word(ptr($0040, $0008 + (i - 1) * 2)^);π If Par[i] = 0 thenπ Writeln('Not Found')π elseπ Writeln(Par[i]);π end;πend.πππ 8 05-28-9313:48ALL SWAG SUPPORT TEAM SCSICODE.PAS IMPORT 30 └╫Hv {π > I am trying to issue an SCSI START/StoP Unit via Adaptec's ASPI SCSIπ > manager and an 1542B host adaptor. This is For an application I amπ > writing in BP. Adaptec is of no help. if anyone here has anyπ > commentsπ > or suggestions please respond in this Forum.π}ππUnit Aspi;ππ{ I/O Error reporting:ππ AspiSenseKey is the primary source of error inFormation.ππ 0: I/O Complete.π Warnings (Filemark, Short block, etc) may be posted in Sense.ππ 1-E: Error occured.π Examine SRBStat, HostStat, TargStat, Sense For details.ππ F: Severe error detected, no SCSI info available.ππ -------------------------------------------------------------------- }ππInterfaceππConstπ SrbIn = $08;π SRBOut = $10;π SRBNone = $18;π AspiPtr: Pointer = Nil;πππTypeπ AspiSrb = Recordπ SrbCmd: Byte;π SrbStat: Byte;π SrbHost: Byte;π SrbReqFlags: Byte;π SrbHdrFill: LongInt;π Case Integer ofπ 2: (Srb2TargetID: Byte;π Srb2LUN: Byte;π Srb2DataLen: LongInt;π Srb2SenseLen: Byte;π Srb2DataPtr: Pointer;π Srb2LinkPtr: Pointer;π Srb2CDBLen: Byte;π Srb2HAStat: Byte;π Srb2TargStat: Byte;π Srb2PostAddr: Pointer;π Srb2Filler: Array [1..34] of Byte;π { Sense data follows CDB }π Srb2CDB: Array [0..50] of Byte);π 1: (Srb1TargetID: Byte;π Srb1LUN: Byte;π Srb1DevType: Byte);π 0: (Srb0Cnt: Byte;π Srb0TargetID: Byte;π Srb0MgrID: Array [1..16] of Char;π Srb0HostID: Array [1..16] of Char;π Srb0HostParm: Array [1..16] of Char);π end;ππVarπ AspiSRBStat: Byte;π AspiHostStat: Byte;π AspiTargStat: Byte;π AspiSenseKey: Byte;π AspiSense: Array [0..17] of Byte;π AspiSenseCode: Word;ππFunction AspiOpen: Integer;ππProcedure AspiCall (Var SRB: AspiSrb);π{ Call ASPI Handler With SRB }πInline ($FF/$1E/>AspiPtr/π $58/$58);ππProcedure AspiWait (Var SRB: AspiSrb);ππFunction AspiClose: Integer;ππImplementationππUses Dos;ππProcedure AspiWait (Var SRB: AspiSRB);π{ Call ASPI Handler With SRB and wait For Completion }πbeginπ if AspiPtr = Nilπ then beginπ AspiSenseKey := $0F;π Exit;π end;π With Srb do beginπ SrbStat := 0;π AspiCall (Srb);π While SrbStat = 0 do ;π AspiSrbStat := SrbStat;π AspiHostStat := Srb2HAStat;π AspiTargStat := Srb2TargStat;π AspiSenseKey := 0;π FillChar (AspiSense, Sizeof (AspiSense), #0);π Move (Srb2CDB [Srb2CDBLen], AspiSense, Sizeof (AspiSense));π AspiSenseKey := AspiSense[2] and $0F;π AspiSenseCode := (AspiSense [12] SHL 8) or AspiSense [13];π end;π end;ππFunction AspiOpen: Integer;πConstπ AspiName: Array [1..9] of Char = 'SCSIMGR$'#0;πVarπ R: Registers;π AspiHan: Word;πbeginπ With R do beginπ { Assume failure }π AspiOpen := -1;π AspiPtr := Nil;ππ { Open ASPI device driver }π AX := $3D00;π DS := Seg (AspiName[1]);π DX := ofs (AspiName[1]);π MSDos (R);π if odd (Flags)π then Exit;π AspiHan := AX;ππ { Do IOCtl Read to get Pointer to ASPI handler }π AX := $4402;π BX := AspiHan;π CX := 4;π DS := Seg (AspiPtr);π DX := ofs (AspiPtr);π MSDos (R);π if Odd (flags)π then Exit;ππ { Close device driver }π AX := $3E00;π BX := AspiHan;π MsDos (R);π if Odd (Flags)π then Exit;π end;ππ { Indicate success and Exit }π AspiOpen := 0;π end { AspiOpen };ππFunction AspiClose: Integer;πbeginπ AspiClose := 0;πend { AspiClose };ππend.π 9 05-28-9313:48ALL SWAG SUPPORT TEAM SECTORIO.PAS IMPORT 65 └╫x {... so there I was, sitting in a bar when a known C Programmer }π{comes up to me and sniggers "still doing it in Pascal eh?" }π{"Yup" I replied, and tossed the bartender another hundred. }π{"Yeah well, when you're ready For a Real language, only C has }π{all the aces." }π{I'm a Pascal Programmer. I don't have to take that. "Such as?"}π{I hoped he'd bite and he did. }π{"Such as disk sector reading and writing For starters." }π{"Well I hope you're not bluffin', 'cause here's a trick that }π{I'll bet you ain't covered." }π{I pulled it out With a swish and laid it on the table. "Even }π{provides support For >32M volumes, which the C run-time library }π{manual Forgets to tell you it won't do." }π{"Huh? Where?" }π{"Right here" I said. "Just where it says... }ππProgram AbsReadTest;ππ{This Program demonstrates a C-style absread and absWrite For TP.}π{As is, it reads the boot sector off drive A:, and optionally }π{Writes it out to the very last sector on drive A: (assumes 1.2Meg}π{This Program IS dangerous, and is released to the public domain.}π{I take no responsibility For use or misuse, deliberate or }π{accidental, of this Program or any Program which Uses the }π{techniques described herein. }ππ{Author: Mitch Davis 3:634/384.6 +61-3-890-2062 v1.0 28-Jun-92. }ππVar bp:Pointer; {Will point to the buffer For the sector data}ππFunction absread (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;ππ{Works just like the C runtime one- including being restricted to 32M volumes!}ππ{drive is a Character, nsects is the number of sectors, and lsect is the first}π{sector. buffer points to the buffer you'd like filled from disk. Function }π{returns True if there was an error, or False if all went well. }ππVar kludgebuff:Array [0..$1f] of Byte; {Read Ralf Brown's interrupt listing}π kludgePtr:Pointer; {Int 25h - ES:[BP+1E] may change }ππbeginπ kludgePtr := @kludgebuff;π absread := True;π if drive < 'A' then Exit;π if drive > 'Z' then Exit;π Asmπ push esπ push bpπ push diπ les di, kludgePtrπ mov al, drive { Gets the passed parameter. }π and al, 1fh { Cvt from ASCII to drive num }π dec al { Adjust because A: is drive 0 }π mov cx, nsects { number of sectors to read }π mov dx, lsect { starting at sector.. }π push dsπ lds bx, buffer { Get the address of the buffer }π mov bp, diπ push siπ int 25h { Do the drive read. }π pop si { Remove the flags int 25h leaves on stack}π pop siπ pop dsπ pop diπ pop bpπ pop esπ jc @1π mov ah, 0 { No errors, so set Function to False }π @1:π mov @result, ahπ end;πend;ππFunction absWriteπ (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;ππ{Works just like the C one - including being restricted to 32M volumes!}ππ{drive is a Character, nsects is the number of sectors, and lsect is the first}π{sector. buffer points to the buffer you'd like filled from disk. Function }π{returns True if there was an error, or False if all went well. }ππVar kludgebuff:Array [0..$1f] of Byte;π kludgePtr:Pointer;ππbeginπ kludgePtr := @kludgebuff;π absWrite := True;π if drive < 'A' then Exit;π if drive > 'Z' then Exit;π Asmπ push esπ push bpπ push diπ les di, kludgePtrπ mov al, drive { Gets the passed parameter. }π and al, 1fh { Cvt from ASCII to drive num }π dec al { Adjust because A: is drive 0 }π mov cx, nsects { number of sectors to Write }π mov dx, lsect { starting at sector.. }π push dsπ lds bx, buffer { Get the address of the buffer }π mov bp, diπ push siπ int 26h { Do the drive Write. }π pop si { Remove the flags int 26h leaves on stack}π pop siπ pop dsπ pop diπ pop bpπ pop esπ jc @1π mov ah, 0π @1:π mov @result, ahπ end;πend;ππFunction absLread (drive:Char; nsects:Word; lsect:LongInt;πbuffer:Pointer):Boolean;ππ{This Function reads sectors on disks which have the >32M style made popular}π{by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+. }ππVar packet:Array [0..9] of Byte; {disk request packet - see Ralf Brown's ints}ππbeginπ absLread := True;π if drive < 'A' then Exit;π if drive > 'Z' then Exit;π Asmπ mov ax, Word ptr lsect {Get the LSB of the start sector}π mov Word ptr packet[0], ax {Store it in the packet }π mov ax, Word ptr lsect + 2 {Get the MSB of the start sector}π mov Word ptr packet[2], ax {Store this one too. }π mov ax, nsects {How many sectors to read }π mov Word ptr packet[4], axπ {Insert the Pointer to the data buffer into the packet}π push bp ; push dsπ lds dx, buffer { Get the address of the buffer }π mov Word ptr packet[6], dxπ mov dx, dsπ mov Word ptr packet[8], dxπ mov al, drive { Gets the passed parameter. }π and al, 1fh { Cvt from ASCII to drive num }π dec al { Adjust because A: is drive 0 }π int 25h { Do the drive read. }π pop si { Remove the flags int 25h leaves on stack}π pop dsπ pop bpπ jc @1π mov ah, 0π @1:π mov @result, ahπ end;πend;ππFunction absLWrite (drive:Char; nsects:Word; lsect:LongInt;πbuffer:Pointer):Boolean;ππ{This Function Writes sectors on disks which have the >32M style made popular}π{by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+. }ππVar packet:Array [0..9] of Byte;ππbeginπ absLWrite := True;π if drive < 'A' then Exit;π if drive > 'Z' then Exit;π Asmπ mov ax, Word ptr lsectπ mov Word ptr packet[0], axπ mov ax, Word ptr lsect + 2π mov Word ptr packet[2], axπ mov ax, nsectsπ mov Word ptr packet[4], axπ push bp ; push dsπ lds dx, bufferπ mov Word ptr packet[6], dxπ mov dx, dsπ mov Word ptr packet[8], dxπ mov al, drive { Gets the passed parameter. }π and al, 1fh { Cvt from ASCII to drive num }π dec al { Adjust because A: is drive 0 }π int 26h { Do the drive Write. }π pop si { Remove the flags int 26h leaves on stack}π pop dsπ pop bpπ jc @1π mov ah, 0π @1:π mov @result, ahπ end;πend;ππFunction LongNeeded (drive:Char):Boolean;ππ{This Function returns True or False depending on whether the long versions}π{of absread/absWrite needed to be invoked; that is, it's a drive Formatted }π{in the Dos 4+ >32M style. }π{I strongly suggest you see Ralf Brown's interrupt listing For int21h subfs}π{440d and 53 - they'll tell you all you know to understand the guts of this}π{Function. }ππLabel Escape;ππVar drivestats:Array [0..31] of Byte;ππbeginπ LongNeeded := False;π if drive < 'A' then Exit;π if drive > 'Z' then Exit;π Asmπ push dsπ mov dx, ssπ mov ds, dxπ lea dx, drivestatsπ mov bl, drive { Gets the passed parameter. }π and bl, 1fh { Cvt from ASCII to drive num }π mov ax, 440Dhπ mov cx, 0860hπ int 21hπ jc Escapeπ mov ax, Word ptr drivestats[0Fh]π or ax, axπ jnz Escapeπ mov @Result, 1π Escape:π pop dsπ end;πend;ππbeginπ getmem (bp,2048);π Writeln (LongNeeded ('A'));π Writeln (LongNeeded ('C'));π Writeln (absread ('A',1,0,bp));π(* Writeln (absWrite ('A',1,2399,bp)); *) {remove the comments at your own}π {risk!!!}π freemem (bp,2048);πend.ππ{So I bought him a drink. The poor guy looked like he needed one....}π 10 05-28-9313:48ALL SWAG SUPPORT TEAM Activate TURBO Speed IMPORT 9 └╫}v { Does anyone out there know how to set the Software Turbo Speed on Motherπ boards without hitting the Turbo Switch or the <Ctrl> <Alt> <-> key toπ slow the system and or Speed it up again? Thanks...π}ππProgram speed;πUses Dos,Crt;ππProcedure do_speed(mode : String);πVarπ reg : Registers;π oldmem : Byte;ππbeginπ oldmem := mem[$40:$17];π if UpCase(mode[1]) = 'N' thenπ beginπ reg.al := 74;π Writeln('Speed set to NorMAL MODE');π end elseπ beginπ reg.al := 78;π Writeln('Speed set to TURBO MODE');π end;π mem[$40:$17] := 140;π reg.ah := $4F;π intr($15,reg);π mem[$40:$17] := oldmem;πend;ππbeginπ if paramcount < 1 thenπ beginπ Writeln(' Speed.exe (c) by Werner Schlagnitweit 2:310/3.0');π Writeln(' This Program should work on all machines which ');π Writeln(' use the CTRL-ALT-+ key to toggle the speed ');π Writeln;π Writeln(' Usage : Speed N For normal NON TURBO mode');π Writeln(' Speed T For normal TURBO mode ');π halt;π end else do_speed(paramstr(1));πend.π 11 08-27-9322:08ALL SWAG SUPPORT TEAM Set the TURBO speed IMPORT 6 └╫ {π Does anyone out there know how to set the Software Turbo Speed on Motherπ boards without hitting the Turbo Switch or the <Ctrl> <Alt> <-> key toπ slow the system and or Speed it up again? Thanks...π}ππUsesπ Dos;ππProcedure SetSpeed(Turbo : Boolean);πVarπ Regs : Registers;π OldMem : Byte;ππbeginπ {OldMem := Mem[$40 : $17];}π If Turbo thenπ Regs.AL := 78π elseπ Regs.AL := 74;ππ {Mem[$40 : $17] := 140;}π Regs.AH := $4F;π Intr($15, Regs);π {Mem[$40 : $17] := OldMem;}πend;ππbeginπ SetSpeed(False);πend.π 12 10-28-9311:29ALL BRUCE LACKLORE CPU Info SWAG9311 87 └╫ Unit CPUInfo;ππ{ Version 1.1.0.Pππ Requires Borland Turbo Pascal version 6.0 or later to compile.π Author: Bruce J. Lackore. Created Saturday, October 9, 1993.π}ππ{$IFDEF Test}π {$A+,B-,D+,F-,G-,I+,L+,O-,R+,S+,V-,X+}π{$ELSE}π {$A+,B-,D-,F-,G-,I-,L-,O-,R-,S-,V-,X+}π{$ENDIF}ππ{ This unit contains a handy gadget for determining the CPU speed. It is NOTπ coded for the Pentium family (if anyone wants to take a shot at it, pleaseπ let me know the results)!π}ππInterfaceππConstπ Cpu8086 = 1;π Cpu80286 = 2;π Cpu80386 = 3;π Cpu80486 = 4;ππFunction WhatCPU: Word;ππ{ This function examines the CPU and returns a number corresponding to theπ CPU type; 1 for 8086, 3 for 80386, etc. This procedure came right out ofπ Neil Rubenking's Turbo Pascal 6.0 Techniques and Utilities (thanx Neil!).π}ππProcedure CPUSpd(Var MHz, KHz: Word);ππ{ This procedure is a ROUGH estimation of how fast the CPU is running inπ MegaHertz. It was adapted from a C program found in the Intel forum ofπ CIS written by Glenn Dill. I had to do some finagling of the original codeπ because C allows for a 32-bit UNSIGNED integer, whereas Pascal allows for aπ 32-bit SIGNED integer (the LongInt), therefore, I was forced to reduce allπ calculations by 10 in order to get it to fit properly.π}ππ{ ************************************************************************** }ππImplementationππFunction WhatCPU; Assembler;ππ Asm { Function WhatCPU }π MOV DX,Cpu8086π PUSH SPπ POP AXπ CMP SP,AXπ JNE @OUTπ MOV DX,Cpu80286π PUSHFπ POP AXπ OR AX,4000hπ PUSH AXπ POPFπ PUSHFπ POP AXπ TEST AX,4000hπ JE @OUTπ MOV DX,Cpu80386 { "DB 66h" makes '386 extended instruction }π DB 66h; MOV BX,SP { MOV EBX,ESP }π DB 66h, 83h, 0E4h, 0FCh { AND ESP,FFFC }π DB 66h; PUSHF { PUSHFD }π DB 66h; POP AX { POP EAX }π DB 66h; MOV CX, AX { MOV ECX,EAX }π DB 66h, 35h, 00hπ DB 00h, 04h, 00 { XOR EAX,00040000 }π DB 66h; PUSH AX { PUSH EAX }π DB 66h; POPF { POPFD }π DB 66h; PUSHF { PUSHFD }π DB 66h; POP AX { POP EAX }π DB 66h, 25h,00hπ DB 00h, 04h,00h { AND EAX,00040000 }π DB 66h, 81h,0E1h,00hπ DB 00h, 04h,00h { AND ECX,00040000 }π DB 66h; CMP AX,CX { CMP EAX,ECX }π JE @Not486π MOV DX, Cpu80486π @Not486:π DB 66h; PUSH CX { PUSH ECX }π DB 66h; POPF { POPFD }π DB 66h; MOV SP, BX { MOV ESP,EBX }π @Out:π MOV AX, DXπ End; { Function WhatCPU }ππProcedure CPUSpd;ππ Constπ Processor_cycles: Array[0..4] of Byte = (165, 165, 25, 103, 42);π { Cycle times of 8086, 80186, 80286, 80386, 80486}ππ { Notice that here I have defined the 8086 as a Processor type of 0 viceπ the returned value of 1 from WhatCPU. Since the original code did notπ distinguish between the 8086 and the 80186, I can get away with this.π }ππ Varπ Ticks,π Cycles,π CPS: LongInt;π Which_CPU: Word;ππ Function i86_to_i286: Word; Assembler;ππ Asm { Function i86_to_i286 }π CLIπ MOV CX,1234π XOR DX,DXπ XOR AX,AXπ MOV AL,$B8π OUT $43,ALπ IN AL,$61π OR AL,1π OUT $61,ALπ XOR AL,ALπ OUT $42,ALπ OUT $42,ALπ XOR AX,AXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IDIV CXπ IN AL,$42π MOV AH,ALπ IN AL,$42π XCHG AL,AHπ NEG AXπ STIπ End; { Function i86_to_i286 }ππ Function i386_to_i486: Word; Assembler;ππ Asm { Function i386_to_i486 }π CLIπ MOV AL,$B8π OUT $43,ALπ IN AL,$61π OR AL,1π OUT $61,ALπ XOR AL,ALπ OUT $42,ALπ OUT $42,ALπ DB 66H,$B8,00h,00h,00h,80h;π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π DB 66H,0FH,$BC,$C8; { BSF ECX,EAX }π IN AL,42Hπ MOV AH,ALπ IN AL,42Hπ XCHG AL,AHπ NEG AXπ STIπ End; { Function i386_to_486 }ππ Begin { Procedure CPUSpd }π Which_CPU := WhatCPU;π If Which_cpu < 3 Thenπ Ticks := i86_to_i286π Elseπ Ticks := i386_to_i486;π Cycles := 20 * Processor_cycles[Which_CPU];π CPS := (Cycles * 119318) Div Ticks;π MHz := CPS Div 100000;π KHz := (CPS Mod 100000 + 500) Div 1000π End; { Procedure CPUSpd }ππEnd. { Unit CPUInfo }ππ{ --------------------- TEST PROGRAM --------------------------}ππProgram CPUSpeed;ππ{ Version 1.0.0.T.ππ Requires Borland Turbo Pascal version 6.0 or later to compile.ππ Author: Bruce J. Lackore. Created Saturday, October 9, 1993.π}ππ{$IFDEF Test}π {$A+,B-,D+,E+,F-,G-,I+,L+,N-,R+,S+,V-,X+}π{$ELSE}π {$A+,B-,D-,E+,F-,G-,I-,L-,N-,R-,S-,V-,X+}π{$ENDIF}ππ{$M 1024, 0, 0}ππUses CPUInfo;ππVarπ MHz,π KHz: Word;ππBegin { Program: Cpuspeed }π CpuSpd(MHz, KHz);π Writeln('The CPU speed is ', MHz, '.', KHz, ' MHz.')πEnd. { Program: Cpuspeed }π 13 11-02-9310:33ALL ERIC SCHILKE PORTS Info SWAG9311 15 └╫ {πERIC SCHILKEππ> I need help in obtaining all pertinent information aboutπ> AuxInPtr and AuxOutPtr, as pertaining to TP 3.0 reservedπ> Words. These Pointers are referencing BIOS entry points.ππThis is from memory, since I don't have the references here, andπit has been a While.... AuxInPtr and AuxOutPtr are Pointersπcontaining the addresses of the respective AuxIn Function andπAuxOut Procedure, which are used (and not available as a standardπFunction/Procedure) by the standard TP3 I/O drivers.ππEach of the I/O possibilities has a corresponding Procedure/Function,πaddress Pointer, and BIOS entry point as follows:ππ Device proc/funct address BIOS entryππ CON:,TRM:,KBD: ConIn:Char; ConInPtr CONINπ CON:,TRM:,KBD: ConOut(Ch:Char); ConOutPtr CONOUTπ LST: LstOut(Ch:Char); LstOutPtr LISTπ AUX: AuxIn:Char; AuxInPtr READERπ AUX: AuxOut(ch:Char); AuxOutPtr PUNCHπ USR: UsrIn:Char; UsrInPtr CONIN ?π USR: UsrOut(ch,Char); UsrOutPtr CONOUT ?ππI'm not sure about the last two entry points. Also, if memoryπserves correctly, there is another Function, ConSt:Boolean, whichπis used by the KeyPressed Function, having a corresponding addressπPointer, ConStPtr, With BIOS entry Const. if you Write your own I/Oπdrivers, you should assign the address of the corresponding driverπFunction or Procedure to the proper Pointer Variable. Your questionπis a bit vague; what specific problems have you encountered? Iπthink that my recollection is accurate; however, my old referencesπare in an attic in Pennsylvania, While I am here in Huntsville,πAlabama. Perhaps someone else could confirm and/or amplify onπthese observations.π}π 14 09-26-9308:48ALL GAYLE DAVIS Determine CPU Type SWAG9311 20 └╫ Unit CPU;ππINTERFACEππTypeπ CpuType = ( cpu8088,π cpu8086,π cpu80286,π cpu80386,π cpu80486,π cpuPentium,π cpuFutureπ );π CpuStrType = String[7];ππFunction GetCpuType : CpuType;π { Returns the currently executing CPU type }ππFunction GetCpuTypeStr : CpuStrType;π { Returns the currently executing CPU type as a string }ππIMPLEMENTATIONππConstπ CpuTypeIdentified : Boolean = False;πVarπ ConfirmedCpuType : CpuType;ππ{$L CPU.OBJ}ππ{$F+}πFunction WhichCPU : CpuType;π { Determines and returns the currently executing CPU type }πEXTERNAL;π{$F-}ππProcedure IdentifyCpuType;π { Handles initialization of CPU type }πBeginπ If Not CpuTypeIdentified Thenπ Beginπ ConfirmedCpuType := WhichCPU;π CpuTypeIdentified := True;π End;πEnd; { Procedure IdentifyCpuType }ππFunction GetCpuType : CpuType;π { Returns the currently executing CPU type }πBeginπ IdentifyCpuType;π GetCpuType := ConfirmedCpuType;πEnd; { Function GetCpuType }ππFunction GetCpuTypeStr : CpuStrType;π { Returns the currently executing CPU type as a string }πBeginπ IdentifyCpuType;π Case ConfirmedCpuType Ofπ cpu8088 : GetCpuTypeStr := '8088';π cpu8086 : GetCpuTypeStr := '8086';π cpu80286 : GetCpuTypeStr := '80286';π cpu80386 : GetCpuTypeStr := '80386';π cpu80486 : GetCpuTypeStr := '80486';π cpuPentium : GetCpuTypeStr := 'Pentium';π cpuFuture : GetCpuTypeStr := 'Future';π End; { Case }πEnd; { Function GetCpuTypeStr }ππEnd.π{ eof CPU.PAS }πππNOTE : Cut the following code to a seperate file, and thenπ USE XX34 to DECODE the block which contains CPU.OBJπ needed with this unit.ππ*XX3401-000399-290893--68--85-63424---------CPU.OBJ--1-OF--1πU+s+14BkRKZYMLBh9Y3HHE466++++-lIRL7WPm--QrBZPK7gNL6U63NZQbBdPqsUAmsmπaMUI+21dBaTF4UlXQ5JdN43nPGt-Iop0W+A+ECZAZU6++4W6+k-+cNGK-U+2Eox2FIKMπ-k-6wk+0+E2WY+w+++26JoV7EoV1I3I+++1xW+E+E86-YO1r++2++-uAm6vMu-k+D+7xπ-SUk+CgFu2Y+D+Bw0iVV+1k2T+DcV++TmtmQKs5XzkxHbNlPUSA+w1D+UTg+w5E0g+8RπkkOAm6v+zPc-+9xM+90EiEA+wufwY70EGd0EWw65ktkD+S1Fq5A3i+A+ul0s+5-EbNlMπUCFki+6+R+3+bQC9y6jQNdlab4NMNUo+++E+NZ-abKOQNZVaeE++-+-o+t0EFqORWyC9πlwBab4NMNcjMNXI++0++NZ-abKOQNZVaIqORNWI++0++Nc5X+++U+4MvkrESY7-ai+2+π+++Dch5coSXFuB5coSXFuB5coSUZ1k11i+E+kumQ-E12GJE-zMc0++-oπ***** END OF XX-BLOCK *****πππ 15 11-02-9305:41ALL KAI ROHRBACHER AT Extended BIOS ?? SWAG9311 16 └╫ {πKAI ROHRBACHERππ As promised, here is some TP-code to check whether your machineπ supports the extended timing services of the AT's-BIOS: if all worksπ fine, the Program should give two beeps, the 2nd exactly 5secs afterπ the 1st one -and then terminate.ππ (To all others reading this: this timing scheme normally worksπ _asynchrone_ to whatever you are doing in the "foreground" Program andπ thus is great For timing events. What's more: the clock has aπ resolution of some microseconds!)π}ππConstπ WaitTime = 5000;πVarπ IsAT,π TimeFlag : Byte;π CycleTime : LongInt;ππFunction AT : Boolean;π{ in: - }π{out: True/False, if the machine is (at least) an AT}πbeginπ AT := MEM[$F000 : $FFFE] = $FC;πend;ππProcedure SetWaitingTime(milliseconds : Word);π{ in: milliseconds = time to wait in ms}π{out: CycleTime := that same value in microseconds}π{ TimeFlag := $80}π{rem: won't work With PC's}πbeginπ TimeFlag := $80;π CycleTime := LongInt(milliseconds) * LongInt(1000);π if (milliseconds <> 0) and AT thenπ IsAT := 0 {yes, use timing mechanism}π elseπ IsAT := $80; {no, don't use that extended service}πend;ππProcedure Wait;πbeginπ Asmπ MOV AL, IsATπ or AL, ALπ JNE @L11π MOV TimeFlag,ALπ MOV DX, Word PTR CycleTimeπ MOV CX, Word PTR CycleTime+2π MOV BX, OFFSET TimeFlagπ MOV AX, DSπ MOV ES, AXπ MOV AX, 8300hπ INT 15hπ @L11:ππ @L10:π MOV AL, TimeFlag {look at bit 7: 1/0 = time over/not over}π and AL, $80π JE @L10π end;πend;ππbeginπ if not AT thenπ beginπ WriteLN('Sorry, this Program requires the extended BIOS-' +π 'services, available on AT''s only!');π Halt(1);π end;π WriteLN('The time between the two beeps should be exactly ', WaitTime,π ' milliseconds!');π Write(#7);π SetWaitingTime(5000);π Wait;π Write(#7);πend.π 16 11-02-9304:59ALL KAI ROHRBACHER Which BIOS SWAG9311 9 └╫ {πKAI ROHRBACHERππ> What bios are you using?πIt's an AMI-BIOS, dated 03-06-1992; but I ran the same code on an oldπTandon-AT (with BIOS from 1987) w/o problems, too!ππ> Do you have any other timing code?πNot at hand; one could reProgram the trigger rate of timer 0 to beπfaster than 1/18.2 sec, but in my experience, this results in evenπmore incompatibilities when interfacing the Unit to others.π}ππFunction BIOScompatible : Boolean;πVarπ Flag : Byte;π p : Pointer;πbeginπ Flag := 0;π p := @Flag;π if AT thenπ Asmπ STIπ xor CX, CXπ MOV DX, 1π LES BX, pπ MOV AX, 8300h {trigger 1 microsecond}π INT 15hπ @L11:π end;π Delay(1); {wait 1 ms:}π BIOScompatible := Flag = $80; {has flag been set?}πend;ππ{π ...results in False For you, I can't do much! However, I'll add theπ above routine to disable the timing mechanism in that Case to preventπ the endless loop, at least.π}π 17 11-02-9316:11ALL LAURENT M. CHARTINIER Quick Reset and BOOT SWAG9311 3 └╫ {Laurent M. CHARTINIER}π{computer do a RESET using a small Pascal routine?}ππProcedure Reboot;πBeginπ Asmπ JMP FFFF:0000π End;πEnd;ππ